package com.xxgg.system.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xxgg.common.exception.ApiException;
import com.xxgg.common.exception.Asserts;
import com.xxgg.common.utils.redis.RedissonUtils;
import com.xxgg.system.mapper.MenuMapper;
import com.xxgg.system.mapper.RoleMenuMapper;
import com.xxgg.system.model.po.Menu;
import com.xxgg.system.model.po.Role;
import com.xxgg.system.mapper.RoleMapper;
import com.xxgg.system.model.po.RoleMenu;
import com.xxgg.system.service.RoleService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 先谢郭嘉
 * @since 2023-01-31 04:33:30
 */
@Service
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements RoleService {
    @Resource
    RoleMapper roleMapper;
    @Resource
    MenuMapper menuMapper;
    @Resource
    RoleMenuMapper roleMenuMapper;

    @Override
    public List<String> getRolePermission(Integer roleId) throws ApiException {
        // 获取角色信息
        Role role = roleMapper.selectById(roleId);
        Asserts.isTrue(role == null || StrUtil.isBlank(role.getRoleCode()),"不存在改角色！");

        // 从redis缓存中查询角色权限码集合
        List<String> permissionRedisList = RedissonUtils.getCacheObject("permission:" + role.getRoleCode());
        if (CollUtil.isNotEmpty(permissionRedisList)) {
            return permissionRedisList;
        }

        // redis中不存在角色权限码集合，从数据库中查询
        // 根据角色Id获取角色授权菜单
        List<Menu> menuList = menuMapper.getMenuListByRole(roleId);
        // 从菜单列表中提取出菜单授权码
        List<String> permissionList = menuList.stream().map(Menu::getPermission).collect(Collectors.toList());
        if (CollUtil.isNotEmpty(permissionList)) {
            // 将角色权限码集合存入redis，
            RedissonUtils.setCacheObject("permission:" + role.getRoleCode(), permissionList);
            return permissionList;
        }
        return null;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean updateRoleGrant(Integer roleId, List<String> menuIdList) throws ApiException {
        // 记录数
        long count = 0;
        // 根据角色id获取角色信息（版本号）
        Role role = roleMapper.selectById(roleId);
        Asserts.isTrue(role == null, "不存在该角色！");

        // 查询出该角色的所有权限菜单
        List<RoleMenu> roleMenuList = roleMenuMapper.selectList(new LambdaQueryWrapper<RoleMenu>()
                .eq(RoleMenu::getRoleId, roleId));
        if(roleMenuList.size() > 0){
            // 删除角色和菜单的关联关系
            for(RoleMenu roleMenu : roleMenuList){
                count = roleMenuMapper.delete(new LambdaQueryWrapper<RoleMenu>()
                        .eq(RoleMenu::getRoleId, roleId)
                        .eq(RoleMenu::getMenuId, roleMenu.getMenuId()));
                Asserts.isFalse(count > 0, "角色授权失败（delete）！");
            }
        }

        if(menuIdList.size() > 0){
            // 新增角色和菜单的关联关系
            for(String menuId : menuIdList){
                count = roleMenuMapper.insert(RoleMenu.builder()
                        .menuId(menuId)
                        .roleId(roleId)
                        .build());
                Asserts.isFalse(count > 0, "角色授权失败（add）！");
            }
        }
        return count > 0;
    }
}
